package com.geekchique.runningbuddy.model;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map.Entry;

import com.geekchique.runningbuddy.util.DateUtils;

public class PastJogsCalendar {

	Calendar calendar;
	private LinkedHashMap<Integer, Integer> daysinMonthTable;
	public final int NO_OF_ROWS = 5;
	public final int NO_OF_COLS = 6;
	private String currShowingMonth;
	
	public static final String SHOWING_DATE_FORMAT = "MMM-yyyy";
	public static final String CURRENT_DATE_IN_MONTH_FORMAT = "d";

	public final static int MONDAY_COL = 0;
	public final static int TUESDAY_COL = 1;
	public final static int WEDNESDAY_COL = 2;
	public final static int THURSDAY_COL = 3;
	public final static int FRIDAY_COL = 4;
	public final static int SATURDAY_COL = 5;
	public final static int SUNDAY_COL = 6;
	private SimpleDateFormat showingDateFormatter;
	private String firstIndexOfWeekDay = "00";
	
	public PastJogsCalendar() {
		calendar = new GregorianCalendar();
		daysinMonthTable = new LinkedHashMap<Integer, Integer>();
		showingDateFormatter = new SimpleDateFormat(SHOWING_DATE_FORMAT);
	}	
	
	public void setCurrentMonthTable(int year, int month, int day) {
		calendar.set(Calendar.YEAR, year);
		calendar.set(Calendar.MONTH, month);
		calendar.set(Calendar.DAY_OF_MONTH, day);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		
		
		int firstWeekdayOfMonth = getIndexOfFirstWeekDayOfMonth(calendar);
		int noOfDays = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
		
		setMonthText(showingDateFormatter.format(calendar.getTime()));
		setCellsInTheMonthTable(firstWeekdayOfMonth, noOfDays);
	}

	private void setMonthText(String month) {
		this.currShowingMonth = month;
	}

	protected int getIndexOfFirstWeekDayOfMonth(Calendar calendar) {
		int day = DateUtils.calcFirstOfMonth(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH)); 
		
		if(day == 0){
			day = 7;
		}
		
		return day;
	}

	public void setCellsInTheMonthTable(int firstWeekdayOfMonth, int maxNoOfDaysInMonth) {

		int currentCol = 0, currentRow = 0;
		Integer day = 1;
		String currentIndex = "00";
		
		setPaddingZerosInMonth(firstWeekdayOfMonth);
		
		for(; currentCol < firstWeekdayOfMonth - 1; currentCol++){
			currentIndex = incrementIndex(currentIndex);
		}
		
		while(notInTheLastCellInTable(currentCol, currentRow))
		{ 
			if(firstCellOfNewRow(currentCol)){
				currentRow++;
				currentCol = 0;
				currentIndex = setIndex(currentRow, currentCol);
			}
			
			if( day <= maxNoOfDaysInMonth ) {
				this.daysinMonthTable.put(new Integer(currentIndex), day);
			}else{
				this.daysinMonthTable.put(new Integer(currentIndex), 00);
			}
			
			day++;
			currentCol++;
			currentIndex = setIndex(currentRow, currentCol);
		}
		
	}

	private boolean firstCellOfNewRow(int currentCol) {
		return currentCol > NO_OF_COLS;
	}

	private boolean notInTheLastCellInTable(int currentCol, int currentRow) {
		return !(currentRow == NO_OF_ROWS && firstCellOfNewRow(currentCol));
	}

	private String incrementIndex(String currentIndex) {
		Integer indexRow = new Integer (String.valueOf(currentIndex.charAt(0))); 
		Integer indexCol = new Integer(String.valueOf(currentIndex.charAt(1))); 
		
		indexCol++;
		currentIndex = indexRow.toString() + indexCol.toString();
		return currentIndex;
	}

	private String setIndex(int currentRow, int col) {
		String currentIndex;
		String currCol = new String (Integer.toString(col));
		currentIndex = new String(currentRow + currCol) ;
		return currentIndex;
	}

	public long getCurrentlyShowingDate() {
		return calendar.getTimeInMillis();
	}

	public int get(int dateType) {

		switch(dateType){
			case Calendar.DAY_OF_MONTH: return calendar.get(Calendar.DAY_OF_MONTH);
			case Calendar.MONTH:	return calendar.get(Calendar.MONTH);
			case Calendar.YEAR:		return calendar.get(Calendar.YEAR);
		}
		
		return 0;
	}

	public Calendar getCalendar() {
		return calendar;
	}

	public void setDaysInMonthTable(LinkedHashMap<Integer, Integer> tableOfDays){
		this.daysinMonthTable = tableOfDays;
	}
	
	public LinkedHashMap<Integer, Integer> getDaysInMonthTable() {
		return this.daysinMonthTable;
	}

	public String getCurrentShowingMonth() {
		return currShowingMonth;
	}

	public void setPaddingZerosInMonth(Integer noOfZeros) {
		int currentCol = 0, currentRow =0;
		String currentIndex = "00";
		
		for(; currentCol <= noOfZeros; currentCol++){
			this.daysinMonthTable.put(new Integer(currentIndex), 00);
			currentIndex = setIndex(currentRow, currentCol);
		}
		
		currentIndex = setIndex(currentRow, currentCol);		
		firstIndexOfWeekDay = currentIndex;
	}

	public String getFirstIndexOfWeekDay() {
		return firstIndexOfWeekDay;
	}

	public String getTableIndexOfDay(Integer dayOfMonth) {

		for(Iterator<Entry<Integer, Integer>> iter = daysinMonthTable.entrySet().iterator(); iter.hasNext();){
			Entry<Integer, Integer> cell = iter.next();
			
			if(cell.getValue() == dayOfMonth){
				
				if(cell.getKey() < 10){
					return "0" + cell.getKey().toString();
				}
					
				return cell.getKey().toString();
			}
		}
			
		return null;
	}

}
